class ListNode {
  constructor(val, next = null) {
    this.val = val;   // 节点值
    this.next = next; // 指向下一个节点的指针
  }
}

function reverseKGroup(head, k) {
  // 辅助函数：反转 [a, b) 区间内的节点（左闭右开）
  const reverse = (a, b) => {
    let prev = null, curr = a;
    while (curr !== b) {
      const next = curr.next;
      curr.next = prev; // 反转指针
      prev = curr;
      curr = next;
    }
    return prev; // 返回反转后的头节点（原区间的最后一个节点）
  };

  let dummy = new ListNode(0); // 虚拟头节点（简化边界处理）
  dummy.next = head;
  let prev = dummy; // 记录当前组的前驱节点

  while (head !== null) {
    // 1. 检查剩余节点是否足够 K 个
    let tail = prev;
    for (let i = 0; i < k; i++) {
      tail = tail.next;
      if (tail === null) return dummy.next; // 不足 K 个，直接返回
    }
    const nextHead = tail.next; // 记录下一组的头节点

    // 2. 反转当前 K 个节点（区间 [head, tail.next)）
    const reversedHead = reverse(head, tail.next);

    // 3. 连接前后组
    prev.next = reversedHead; // 前驱节点指向反转后的头
    head.next = nextHead;     // 反转后的尾（原 head）指向下一组头

    // 4. 更新指针，处理下一组
    prev = head;  // 前驱节点移动到当前组的尾（原 head）
    head = nextHead; // 头节点移动到下一组头
  }

  return dummy.next;
}